local EmoTalentUtil = require "packages.emopack.pkg.emopack_talent.util" -- 加载战法核心
local skel = require "packages.emopack.pkg.emopack_talent.talents.core" ---@type SkillSkeleton

local hasTalent = EmoTalentUtil.hasTalent
local logTalent = EmoTalentUtil.logTalent
local invokeTalent = EmoTalentUtil.invokeTalent
local hasStyle = EmoTalentUtil.hasStyle
local discoverTalent = EmoTalentUtil.discoverTalent
local removeTalent = EmoTalentUtil.removeTalent
local getTalents = EmoTalentUtil.getTalents
local addAttachFunc = EmoTalentUtil.addAttachFunc
local addAttachEffect = EmoTalentUtil.addAttachEffect
local gainTalent = EmoTalentUtil.gainTalent
local addInvokedFunc = EmoTalentUtil.addInvokedFunc
local talent_info = EmoTalentUtil.talent_info
local forRandom = EmoTalentUtil.forRandom
local timesCheck = EmoTalentUtil.timesCheck


addAttachFunc("emot_xuezhong", function (player) -- 雪中送炭
  if player.dead then return end
  logTalent(player, "emot_xuezhong")
  local num = 10
  local x = num - player:getHandcardNum()
  if x > 0 then
    player:drawCards(x, skel.name)
    if player.dead then return end
  end
  x = num - player.maxHp
  if x > 0 then
    player.room:changeMaxHp(player, x)
    if player.dead then return end
  end
  x = num - player.hp
  if x > 0 then
    player.room:recover { num = x, skillName = skel.name, who = player, recoverBy = player }
    if player.dead then return end
  end
  x = num - player.shield
  if x > 0 then
    player.room:changeShield(player, x)
  end
end)


addAttachFunc("emot_langzi", function (player) -- 浪子回头
  invokeTalent(player, "emot_langzi")
  local ts = table.slice(getTalents(player), 1, 11)
  for _, t in ipairs(ts) do
    local r = talent_info[t].rarity
    if removeTalent(player, t) then
      discoverTalent(player, { exclude = {"emot_langzi"}, rarity_limit = {r} })
    end
  end
end)


addAttachFunc("emot_zuojian", function (player) -- 作茧自缚
  local room = player.room
  logTalent(player, "emot_zuojian")
  for _, p in ipairs(room:getAlivePlayers()) do
    if not p.dead and player:isEnemy(p) then
      room:setPlayerMark(p, "emot_zuojian", 1)
      room:setPlayerProperty(p, "hp", p.hp * 2)
      room:setPlayerProperty(p, "maxHp", p.maxHp * 2)
    end
  end
end)

addAttachFunc("emot_huoban", function (player) -- 伙伴的力量
  local room = player.room
  local targets = table.filter(room.players, function (p)
    return p ~= player and player:isFriend(p) and not p:hasSkill("emo__yongzhe", true, true)
  end)
  local to ---@type ServerPlayer?
  if #targets > 0 then
    local alives = room:deadPlayerFilter(targets)
    to = table.random(#alives > 0 and alives or targets) -- 优先选择活人队友
    room:doIndicate(player, {to})
    room:delay(600)
    room:handleAddLoseSkills(to, "emo__yongzhe")
  end
  local t = discoverTalent(player)
  if t and to then
    gainTalent(to, t)
  end
end)

addAttachFunc("emot_swordmaster", function (player) -- 刀剑宗师
  local room = player.room
  if player.dead then return end
  for _, id in ipairs(room.draw_pile) do
    local card =  Fk:getCardById(id)
    if card.sub_type == Card.SubtypeWeapon and player:canUseTo(card, player) then
      room:useCard{ from = player, tos = {player}, card = card }
      break
    end
  end
end)

addAttachFunc("emot_huxiao", function (player) -- 虎啸
  if player.dead then return end
  local room = player.room
  logTalent(player, "emot_huxiao")
  for _, to in ipairs(room:getOtherPlayers(player)) do
    if player.dead then break end
    local ids = table.filter(to:getCardIds("h"), function (id)
      return Fk:getCardById(id).trueName == "slash"
    end)
    if #ids > 0 then
      room:doIndicate(player, {to})
      room:obtainCard(player, ids, true, fk.ReasonPrey, player, skel.name)
    end
  end
end)

addAttachFunc("emot_beastking", function (player) -- 兽王
  if player.dead then return end
  logTalent(player, "emot_beastking")
  for _ = 1, 5 do
    if discoverTalent(player, { style = "beast", random = true }) == nil then break end
  end
end)

addAttachFunc("emot_renshan", function (player) -- 人山人海
  if player.dead then return end
  for _ = 1, 6 do
    gainTalent(player, "emot_wuming")
  end
end)

addAttachFunc("emot_jianiang", function (player) -- 佳酿
  if player.dead then return end
  logTalent(player, "emot_jianiang")
  local room = player.room
  local ids = {
    room:printCard("analeptic", Card.Spade, 3).id,
    room:printCard("analeptic", Card.Spade, 6).id,
    room:printCard("analeptic", Card.Spade, 9).id,
  }
  room:obtainCard(player, ids, true, fk.ReasonPrey, player, skel.name)
end)

addAttachFunc("emot_jiamian", function (player) -- 舞会假面
  if player.dead then return end
  invokeTalent(player, "emot_jiamian")
  local t = discoverTalent(player, { rarity_limit = {3}, random = true, exclude = {"emot_jiamian"} })
  if not t or player.dead then return end
  player.room:setPlayerMark(player, "emot_jiamian", t)
end)

addAttachFunc("emot_molin", function (player) -- 墨麟甲
  if player.dead then return end
  local room = player.room
  logTalent(player, "emot_molin")
  for _, slot in ipairs(player.equipSlots) do
    if player.dead then break end
    local subtype = Util.convertSubtypeAndEquipSlot(slot)
    if player:hasEmptyEquipSlot(subtype) then
      local cid = table.find(room.draw_pile, function (id)
        return Fk:getCardById(id).sub_type == subtype
      end)
      if cid then
        room:moveCardIntoEquip(player, cid, skel.name)
      end
    end
  end
end)

addAttachFunc("emot_fuze", function (player) -- 福泽
  if player.dead then return end
  invokeTalent(player, "emot_fuze")
  local room = player.room
  room:changeMaxHp(player, 5)
  if player.dead then return end
  room:recover { num = 5, skillName = skel.name, who = player, recoverBy = player }
  if player.dead then return end
  local t = discoverTalent(player, { rarity = 2 })
  if t then
    for _, to in ipairs(room.alive_players) do
      if not to.dead and to ~= player and player:isFriend(to) then
        gainTalent(to, t)
      end
    end
  end
end)

addAttachFunc("emot_senlin", function (player) -- 富养森林
  if player.dead then return end
  invokeTalent(player, "emot_senlin")
  player:gainAnExtraTurn(true, "emot_senlin")
  if #getTalents(player, {"worm"}) > 0 then
    discoverTalent(player, { style = "worm" })
  end
  if player.dead then return end
  if #getTalents(player, {"beast"}) > 0 then
    discoverTalent(player, { style = "beast" })
  end
end)

addAttachFunc("emot_tongbi", function (player) -- 古代铜币
  if player.dead then return end
  invokeTalent(player, "emot_tongbi")
  EmoTalentUtil:addMoney(player, 50)
  player.room:setPlayerMark(player, "emot_tongbi", 1)
end)


-- 获得任何战法时，触发以下内容

addAttachEffect(function (player, t) -- 光合作用
  player.room:addPlayerMark(player, "emot_guanghe-turn")
end)

addAttachEffect(function (player, t) -- 渊博
  if player.dead or t == "emot_yuanbo" or not hasTalent(player, "emot_yuanbo") then return end
  logTalent(player, "emot_yuanbo")
  local room = player.room
  room:addPlayerMark(player, MarkEnum.AddMaxCards, 2)
  player:drawCards(2, skel.name)
end)

addAttachEffect(function (player, t) -- 书虫
  if player.dead or t == "emot_shuchong" or not hasTalent(player, "emot_shuchong")
  or not timesCheck(player, "emot_shuchong") then return end
  local info = talent_info[t]
  if info and info.rarity == 3 then
    invokeTalent(player, "emot_shuchong")
    discoverTalent(player, { rarity_limit = {1} })
  end
end)

addAttachEffect(function (player, t) -- 仿生技术
  if player.dead or t == "emot_fangsheng" or not hasTalent(player, "emot_fangsheng")
  or not timesCheck(player, "emot_fangsheng") then return end
  if hasStyle(t, "beast") or hasStyle(t, "worm") then
    invokeTalent(player, "emot_fangsheng")
    discoverTalent(player, { style = "mech" })
  end
end)

addAttachEffect(function (player, t) -- 黄金雕像
  if player.dead or not hasTalent(player, "emot_jinxiang") or not timesCheck(player, "emot_jinxiang") then return end
  local info = talent_info[t]
  if info and info.rarity == 2 then
    invokeTalent(player, "emot_jinxiang")
    EmoTalentUtil:addMoney(player, 30)
  end
end)


-- 发动“触发型”战法时，触发以下效果

addInvokedFunc(function (player, invoked_talents) -- 回收模组
  if not hasTalent(player, "emot_huishou") then return end
  local first = false
  for _, t in ipairs(invoked_talents) do
    if hasStyle(t, "mech") then
      if player.dead or not timesCheck(player, "emot_huishou") then break end
      if not first then
        first = true
        invokeTalent(player, "emot_huishou")
      end
      player:drawCards(1, skel.name)
    end
  end
end)

addInvokedFunc(function (player, invoked_talents) -- 大学
  if not player.dead and hasTalent(player, "emot_daxue") and timesCheck(player, "emot_daxue") then
    local check = false
    for _, t in ipairs(invoked_talents) do
      if talent_info[t].rarity == 1 and forRandom(player, 0.2, "emot_daxue") then
        check = true
        break
      end
    end
    if check then
      invokeTalent(player, "emot_daxue")
      discoverTalent(player, { rarity_limit = {2} })
    end
  end
end)


